const Redis = require('ioredis')

function RedisConnector () {
  this.redis = null
  this._status = false
}

RedisConnector.prototype.init = function (conf, callback) {
  const redis = new Redis({
    port: conf.port,
    host: conf.host,
    db: conf.db,
    password: conf.password,
    retryStrategy (times) {
      return Math.min(times * 10, 2000) // delay in ms
    }
  })
  redis.on('connect', () => {
    this._status = true
    this.redis = redis
    callback(null)
  })
  redis.on('error', (err) => {
    this._status = false
    callback(err)
  })
}

RedisConnector.prototype.get = function (key, callback) {
  callback = callback || (() => {})
  return new Promise((resolve, reject) => {
    this.redis.get(key, (err, value) => {
      if (err) {
        reject(err)
        return callback(err, null)
      }
      if (!value) {
        resolve(null)
        return callback(null, null)
      }
      try {
        value = JSON.parse(value)
      } catch (err) {
        reject(err)
        return callback(err, null)
      }
      resolve(value)
      return callback(null, value)
    })
  })
}

RedisConnector.prototype.set = function (key, value, time, callback) {
  if (typeof time === 'function') {
    callback = time
    time = null
  }
  if (!value) {
    return callback(null, null)
  }

  callback = callback || (() => {})

  return new Promise((resolve, reject) => {
    try {
      value = JSON.stringify(value)
    } catch (e) {
      reject(e)
      return callback(e, null)
    }
    if (!time) {
      this.redis.set(key, value, () => {
        resolve()
        callback()
      })
    } else {
      this.redis.setex(key, time, value, () => {
        resolve()
        callback()
      })
    }
  })
}

RedisConnector.prototype.del = function (key, callback) {
  callback = callback || (() => {})
  return new Promise((resolve) => {
    this.redis.del(key, () => {
      resolve()
      callback()
    })
  })
}

module.exports = new RedisConnector()
